package common

import (
	"fmt"
	"github.com/imroc/req"
	"github.com/mattn/go-isatty"
	"net/http"
	"net/url"
	"os"
	"path"
	"strings"
)

func DownloadFile(p *DownItem) error {
	filename := path.Join(p.StoreDir, p.Package.Location.Href)

	// 若文件存在，则直接校验 HASH 值 .
	if IsFile(filename) {
		checksumExists, err := FileChecksum(filename, p.Package.Checksum.Type)

		if err != nil {
			return err
		}

		if checksumExists == p.Package.Checksum.Value {
			return nil
		}
	}

	var r *req.Resp

	// fmt.Printf("%p\n", p.Package)

	err := req.SetProxy(func(r *http.Request) (*url.URL, error) {
		if p.RepoItem.UseProxy {
			return url.Parse(p.ProxyUrl)
		}
		return nil, nil
	})

	// 检查是否终端环境？
	if isatty.IsTerminal(os.Stdout.Fd()) {
		r, err = req.Get(fmt.Sprintf("%s/%s", strings.TrimRight(p.RepoUrl, "/"), strings.TrimLeft(p.Package.Location.Href, "/")), req.DownloadProgress(func(current, total int64) {
			fmt.Print(fmt.Sprintf("%.2f%%\r", float32(current)/float32(total)*100))
		}))
	} else {
		r, err = req.Get(fmt.Sprintf("%s/%s", p.RepoUrl, p.Package.Location.Href))
	}

	if err != nil {
		return err
	}

	filedir := path.Dir(filename)

	err = os.MkdirAll(filedir, 777)

	if err != nil {
		return err
	}

	err = r.ToFile(filename)

	if err != nil {
		return err
	}

	checksum, err := FileChecksum(filename, p.Package.Checksum.Type)

	if err != nil {
		return err
	}

	verified := false

	if checksum == p.Package.Checksum.Value {
		verified = true
	}

	if p.Package.Version.Epoch > 0 {
		fmt.Println(fmt.Sprintf("OK (%s, size: %s, version: %s, release: %s, epoch: %d, %s:%s, %s)", p.Package.Name, ByteCountSI(int64(p.Package.Size.Package)), p.Package.Version.Version, p.Package.Version.Release, p.Package.Version.Epoch, p.Package.Checksum.Type, checksum, IIF(verified, "\033[1;32mVerified\033[0m", "\033[1;31mFailed\033[0m")))
	} else {
		fmt.Println(fmt.Sprintf("OK (%s, size: %s, version: %s, release: %s, %s:%s, %s)", p.Package.Name, ByteCountSI(int64(p.Package.Size.Package)), p.Package.Version.Version, p.Package.Version.Release, p.Package.Checksum.Type, checksum, IIF(verified, "\033[1;32mVerified\033[0m", "\033[1;31mFailed\033[0m")))
	}

	return nil
}
